use std::io::{stdout, Write};

use ansi_to_tui::IntoText;
use ratatui::{buffer::Buffer, layout::Rect, widgets::{Paragraph, Widget}};

use super::Folder;
use crate::{core::{adapter::Kitty, manager::PreviewData}, ui::{Ctx, Term}};

pub struct Preview<'a> {
    cx: &'a Ctx,
}

impl<'a> Preview<'a> {
    pub fn new(cx: &'a Ctx) -> Self { Self { cx } }
}

impl<'a> Widget for Preview<'a> {
    fn render(self, area: Rect, buf: &mut Buffer) {
        // 检查是否需要隐藏预览 
        if self.cx.input.visible || self.cx.select.visible || self.cx.tasks.visible {
            stdout().write(Kitty::image_hide()).ok();
            return;
        }
        // 获取当前悬停的文件
        let manager = &self.cx.manager;
        let hovered = if let Some(h) = manager.hovered() {
            h.clone()
        } else {
            stdout().write(Kitty::image_hide()).ok();
            return;
        };
        // 检查预览数据是否与当前悬停文件匹配
        let preview = manager.active().preview();
        if preview.path != hovered.path {
            return;
        }

        if !matches!(preview.data, PreviewData::Image(_)) {
            stdout().write(Kitty::image_hide()).ok();
        }
        // 根据预览类型不同进行渲染
        match &preview.data {
            PreviewData::None => {}  // 无数据  不渲染  
            PreviewData::Folder => {  
                //  文件夹预览 递归显示文件夹内容 
                if let Some(folder) = manager.active().history(&hovered.path) {
                    Folder::new(self.cx, folder).with_preview(true).render(area, buf);
                }
            }
            PreviewData::Text(s) => {
                // 文本预览  将ANSI转义序列转化为终端样式并渲染
                let p = Paragraph::new(s.as_bytes().into_text().unwrap());
                p.render(area, buf);
            }
            PreviewData::Image(b) => {
                // 图像预览 使用Kitty协议显示图像 
                Term::move_to(area.x, area.y).ok();
                stdout().write(b).ok();
            }
        }
    }
}
